package at.jku.ssw.fortress.ui;

import org.eclipse.jface.bindings.keys.KeySequence;
import org.eclipse.jface.bindings.keys.ParseException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.ITokenScanner;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;

import at.jku.ssw.fortress.ui.assistant.ContentAssistProcessor;
import at.jku.ssw.fortress.ui.html.HTMLTextPresenter;
import at.jku.ssw.fortress.util.ColorManager;

public class Configuration extends TextSourceViewerConfiguration {
	
	private final ColorManager colorManager;
	private final Editor editor;
	
	public Configuration(Editor editor, ColorManager colorManager) {
		this.editor = editor;
		this.colorManager = colorManager;
	}
	
	@Override
	public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
		return new String[] { IDocument.DEFAULT_CONTENT_TYPE, ContentTypes.COMMENT };
	}
	
	@Override
	public IPresentationReconciler getPresentationReconciler(
			ISourceViewer sourceViewer) {
		PresentationReconciler pr = new PresentationReconciler();
		DefaultDamagerRepairer dr;

		dr = new DefaultDamagerRepairer(getDefaultScanner());
		pr.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
		pr.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);

		dr = new DefaultDamagerRepairer(getCommentScanner());
		pr.setDamager(dr, ContentTypes.COMMENT);
		pr.setRepairer(dr, ContentTypes.COMMENT);
		
		dr = new DefaultDamagerRepairer(getStringScanner());
		pr.setDamager(dr, ContentTypes.STRING);
		pr.setRepairer(dr, ContentTypes.STRING);

		return pr;
	}

	private CodeScanner defaultScanner;

	private ITokenScanner getDefaultScanner() {
		if (defaultScanner == null) {
			defaultScanner = new CodeScanner(colorManager);
		}
		return defaultScanner;
	}

	private RuleBasedScanner commentScanner;

	private ITokenScanner getCommentScanner() {
		if (commentScanner == null) {
			commentScanner = new RuleBasedScanner();
			Token comment = new Token(new TextAttribute(colorManager.getColor(ColorConstants.COMMENT)));
			commentScanner.setDefaultReturnToken(comment);
		}
		return commentScanner;
	}

	private RuleBasedScanner stringScanner;
	
	private ITokenScanner getStringScanner() {
		if (stringScanner == null) {
			stringScanner = new RuleBasedScanner();
			Token comment = new Token(new TextAttribute(colorManager.getColor(ColorConstants.STRING)));
			stringScanner.setDefaultReturnToken(comment);
		}
		return stringScanner;
	}
	
	@Override
	public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
		ContentAssistant assistant = new ContentAssistant();
		ContentAssistProcessor processor = new ContentAssistProcessor(assistant);
		try {
			assistant.setRepeatedInvocationTrigger(KeySequence.getInstance("Ctrl+SPACE"));
			assistant.setRepeatedInvocationMode(false);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		assistant.addCompletionListener(processor);
		assistant.setStatusLineVisible(true);
		assistant.setStatusMessage("Press 'Ctrl+Space' to show other proposals");
		assistant.setShowEmptyList(true);
		assistant.setContentAssistProcessor(processor, IDocument.DEFAULT_CONTENT_TYPE);
		
		assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY); 
		assistant.setInformationControlCreator(new IInformationControlCreator() {
			public IInformationControl createInformationControl(Shell parent) {
				return new DefaultInformationControl(parent, SWT.NONE, new HTMLTextPresenter(true));
			}
		});
		return assistant;
	}
	
}
